// 
// Author: damphat@gmail.com
//

#pragma once

#include "vn/BasicTypes.h"
#include "vn/TimeSpan.h"
#include "vn/String.hpp"


//////////////////////////////////////////////////////////////////////////
/// class DateTime - date time calculation in miliseconds, get system time

class DateTime
{
public:
	/// Full-param constructor
	DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond);
	/// No milisecond constructor
	DateTime(int year, int month, int day, int hour, int minute, int second);
	/// Date constructor
	DateTime(int year, int month, int day);
	/// Milisecond constructor
	DateTime(Int64 miliseconds = 0);

	/// Get date part of datetime include (year, month, day)
	const DateTime GetDate() const;

	// TIME:

	int GetHour() const;			/// Hour
	int GetMinute() const;			/// Minute
	int GetSecond() const;			/// Second
	int GetMillisecond() const;		/// Millisecond

	// DATE:

	int GetYear() const;			/// Year
	int GetMonth() const;			/// Month
	int GetDay() const;				/// Day

	/// Day of week; 0 is Sunday, 1 is Monday, ...
	int GetDayOfWeek() const;

	/// Day of year; return a number from 1 to 366
	int GetDayOfYear() const;

	/// Return a datetime string including date part and time part
	String ToString() const;

	/// Return a datetime in several format
	/// \param format: is one of following string
	/// "dd/mm/yyyy"
	/// "ddmmyyyy"
	///	"ddmmyy"
	/// "hh:mm:ss"
	/// "hh:mm:ss.sss"
	String ToString(String format) const;

public:
	Int64 data;						/// miliseconds from date 01/01/01 time 00:00:00

public:
	/// Get current datetime of system
	static const	DateTime Now();

	/// Get current date of system
	static const	DateTime Today();

	/// Check if a year is leap year.
	/// \param year
	static bool		IsLeapYear(int year);

	/// Get number of days in a specified month.
	/// \param year
	/// \param month
	static int		DaysInMonth(int year, int month);

private:
	int				GetDatePart(int part) const;

	static Int64	TimeToMilisecond(int hour, int minute, int second);
	static Int64	DateToMilisecond(int year, int month, int day);

private:
	static int DaysToMonth365[];
	static int DaysToMonth366[];
};

// Add or remove an amount of time
DateTime	operator + (DateTime d, TimeSpan t);	///
DateTime	operator - (DateTime d, TimeSpan t);	///

// Duration between two DateTime
TimeSpan	operator - (DateTime d1, DateTime d2);	///

// Compare two DateTime
bool		operator ==(DateTime d1, DateTime d2);	///
bool		operator !=(DateTime d1, DateTime d2);	///
bool		operator < (DateTime t1, DateTime t2);	///
bool		operator <=(DateTime t1, DateTime t2);	///
bool		operator > (DateTime t1, DateTime t2);	///
bool		operator >=(DateTime t1, DateTime t2);	///
